package com.gr.staffpm.tasks.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.Session;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.gr.staffpm.datatypes.Task;
import com.gr.staffpm.datatypes.TaskComment;
import com.gr.staffpm.datatypes.TaskImportance;
import com.gr.staffpm.datatypes.TaskStatus;
import com.gr.staffpm.datatypes.User;
import com.gr.staffpm.pages.schedule.Schedule;
import com.gr.staffpm.pages.schedule.model.Calendar;
import com.gr.staffpm.pages.schedule.model.Event;
import com.gr.staffpm.tasks.dao.TaskDAO;

/**
 * Default implementation of the {@link TaskService} interface.  This service implements
 * operations related to TaskComment data.
 */
@Transactional
@Service("taskService")
public class DefaultTaskService implements TaskService {

    private TaskDAO taskDAO;

    @Autowired
    public void setTaskDAO(TaskDAO taskDAO) {
        this.taskDAO = taskDAO;
    }

    @Override
    public TaskComment getComment(int id) {
        return taskDAO.getComment(id);
    }

    @Override
    public List<TaskComment> getAllComments(Task task) {
        return taskDAO.getAllComments(task, TaskComment.CREATED, true);
    }

    @Override
    public List<TaskComment> getComments(Task task, int first, int count, String property, boolean ascending) {
        List<TaskComment> comments = taskDAO.getAllComments(task, property, ascending);
        if ((first + count) > comments.size()) {
            comments = comments.subList(first, comments.size() - 1);
        } else
            comments = comments.subList(first, first + count);
        return comments;
    }

    @Override
    public void addComment(TaskComment comment) {
        taskDAO.addComment(comment);
    }

    @Override
    public Task getTask(int id) {
        return taskDAO.getTask(id);
    }

    @Override
    public void updateTask(Task task) {
        taskDAO.updateTask(task);
    }

    @Override
    public List<TaskStatus> getAllStatuses() {
        return taskDAO.getAllStatuses();
    }

    @Override
    public List<TaskImportance> getAllImportances() {
        return taskDAO.getAllImportances();
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#getInProgressStatus()
     */
    @Override
    public TaskStatus getInProgressStatus() {
        return taskDAO.getInProgressStatus();
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#getOpenStatus()
     */
    @Override
    public TaskStatus getOpenStatus() {
        return taskDAO.getOpenStatus();
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#getClosedStatus()
     */
    @Override
    public TaskStatus getClosedStatus() {
        return taskDAO.getClosedStatus();
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#getTasks(java.util.Date, java.util.Date)
     */
    @Override
    public List<Task> getTasksDueBetween(Date startDate, Date endDate) {
        return taskDAO.getTasksDueBetween(startDate, endDate);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#getTasksDueOn(java.util.Date)
     */
    @Override
    public List<Task> getTasksDueOn(Date date) {
        return taskDAO.getTasksDueOn(date);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#getUserTasks(com.gr.staffpm.datatypes.User)
     */
    @Override
    public List<Task> getUserTasks(User user) {
        return taskDAO.getUserTasks(user);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#findTask(java.lang.String)
     */
    @Override
    public List<Task> findTask(String query) {
        return taskDAO.findTask(query);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#getSession()
     */
    @Override
    public Session getSession() {
        return taskDAO.getSession();
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#createIndex()
     */
    @Override
    public void createIndex() {
        taskDAO.createIndex();
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#getUnresolvedUserTasksBetweenDates()
     */
    @Override
    public List<Task> getUnresolvedUserTasksBetweenDates(User user, Date start, Date end) {
        return taskDAO.getUnresolvedUserTasksBetweenDates(user, start, end);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.tasks.service.TaskService#getTasksDueBetweenIncBA(org.joda.time.DateTime, org.joda.time.DateTime)
     */
    @Override
    public List<Event> getTasksDueBetweenForUser(Schedule schedule, User user, DateTime start, DateTime end) {
        List<Event> events = new ArrayList<Event>();
        List<Task> tasksOnWeek = taskDAO.getUnresolvedUserTasksBetweenDates(user, start.toDate(), end.toDate());
        Calendar cal = new Calendar(1);
        schedule.addCalendar(cal);
        for (Task task : tasksOnWeek) {
            Event event = new Event();
            event.setTitle("Task " + task.getName() + " is due");
            event.setAllDay(true);
            event.setStart(new DateTime(task.getDueDate()));
            event.setEnd(new DateTime(task.getDueDate()));
            event.setReminder(0);
            event.setCalendar(cal);
            events.add(event);
        }
        return events;
    }

}
